<template>
  <div class="text2img">
    <div class="text2img-edit">
      <el-icon class="text2img-edit__icon"><Menu /></el-icon>
      <el-input v-model="inputText" placeholder="请输入转换的文字" clearable></el-input>
    </div>
    <div class="text2img-config">
      <template v-if="customJson">
        <div class="config-item" style="width: 95%">
          <pre>
            {{  customJson  }}
          </pre>
        </div>
      </template>
      <template v-else>
        <div class="config-item">
        <el-input
          v-model="fontFamily"
          placeholder="输入自定义字体"
          clearable
        >
          <template #prepend>字体：</template>
        </el-input>
      </div>
      <div class="config-item">
        <el-input
          v-model="fontSize"
          placeholder="输入自定义字号"
          maxlength="2"
          clearable
        >
          <template #prepend>字号：</template>
          <template #append>px</template>
        </el-input>
      </div>
      <div class="config-item">
        <el-input
          v-model="fontColor"
          placeholder="输入自定义字色"
          clearable
        >
          <template #prepend>字色：</template>
        </el-input>
      </div>
      <div class="config-item">
        <el-input
          v-model="fontWeight"
          placeholder="输入自定义字重"
          clearable
        >
          <template #prepend>字重：</template>
        </el-input>
      </div>
      <div class="config-item" style="width: 120px">
        <el-input
          v-model="imgScale"
          placeholder="scale值"
          maxlength="3"
        >
          <template #prepend>scale：</template>
        </el-input>
      </div>
      <div class="config-item" style="justify-content: flex-start; margin-top: 0; width: calc(98% - 120px);">
        <span style="">自定义背景色：</span>
        <el-checkbox v-model="isCustomBgColor" @change="isCustomBgColorChange" :value="true" size="large" />
        <el-input
          v-if="isCustomBgColor"
          style="margin-left: 10px; width: 118px;"
          v-model="customBgColor"
          clearable
          placeholder="自定义背景色, 如#ffffff"
        >
        </el-input>
        <span style="margin-left: 5px;" v-else>默认透明</span>
      </div>
      </template>
    </div>
    <div class="transform-btn">
      <template v-if="customJson">
        <el-button type="primary"  @click="isCustomJson = true">编辑Css</el-button>
        <el-button type="danger" @click="clearCustomCss">清空并返回</el-button>
      </template>
      <el-button type="info" v-else @click="customCss">自定义Css代码</el-button>
      <el-button type="primary" :disabled="!inputText" @click="generateAndUploadImage">生成图片</el-button>
    </div>
    <div ref="textContainer" class="text-container"
    :style="textContainerStyle">{{ inputText }}</div>
    <div class="text2img-show">
      <span class="text2img-show__title">预览区（点击图片可复制Minio地址~ ）：</span>
      <div class="transform-img">
        <el-image class="imgs" :src="imageUrl" @click="toCopy">
        <template #error>
          <div class="image-slot">
            <el-icon><Picture /></el-icon>
          </div>
        </template>
      </el-image>
      </div>
    </div>
    <el-dialog class="text2img-dialog" top="10px" v-model="isCustomJson" title="自定义Css代码" width="360">
      <el-form :model="formData">
      <el-form-item label="">
        <el-input v-model="formData.json" autocomplete="off" 
          :rows="15"
          resize="none"
          type="textarea" />
          <span class="tips">注意: 格式按照需 VUE 行內样式格式來，如:style={ fontSize: '16px' }, json错误则不会生效。</span>
      </el-form-item>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="customDialogCancel">取消</el-button>
        <el-button type="primary" @click="customDialogSave">设置</el-button>
      </div>
    </template>
  </el-dialog>
  </div>
</template>
<script lang="ts">
import { toUpload } from "@/api";
import {ElMessage, ElMessageBox } from 'element-plus';
import {ref, reactive, computed} from 'vue';
import {copy} from "@/utils/tools";
import html2canvas from 'html2canvas';

export default {
  name: 'TextToImage',
  setup() {
    interface Row {
      link: string
      originalName: string
    }
    const inputText = ref<string>('');
    const textContainer = ref<HTMLElement | null>(null);
    const imageUrl = ref('')
    const fontColor = ref('#000000')
    const fontSize = ref('16')
    const fontWeight = ref('400')
    const imgScale = ref('1')
    const isCustomBgColor = ref(false)
    const customBgColor = ref('#ffffff')
    const isCustomJson = ref(false)
    const customJson = ref('')
    const defalutJson = `{
fontSize: '16px',
color: '#000000',
fontWeight: 400,
fontFamily: 'PingFang SC, Helvetica Neue, Helvetica, Arial, sans-serif, Microsoft YaHei'
}`
    const formData = reactive({
      json: defalutJson
    })

    const fontFamily = ref('"PingFang SC", "Helvetica Neue", Helvetica, Arial, sans-serif, "Microsoft YaHei"')

    const textContainerStyle = computed(() => {
      if(customJson.value) {
        let formattedJson = customJson.value;
        // 使用正则表达式替换键名的引号
        formattedJson = formattedJson.replace(/(\w+):/g, '"$1":');
        // 替换属性值中的单引号为双引号
        formattedJson = formattedJson.replace(/'([^']*)'/g, '"$1"');
        // 处理包含转义字符的双引号问题
        formattedJson = formattedJson.replace(/"((?:\\.|[^"\\])*)"/g, function(match, p1) {
            return '"' + p1.replace(/\\/g, '\\\\').replace(/"/g, '\\"') + '"';
        });
        try {
          return JSON.parse(formattedJson)
        } catch(e) {
          return {}
        }
      }
      return {
        fontWeight: fontWeight.value,
        color: fontColor.value,
        fontFamily: fontFamily.value,
        fontSize: fontSize.value.includes('px') ? fontSize.value : `${fontSize.value}px`
      }
    })
    /* 生成圖片 */
    const generateAndUploadImage = async () => {
      if (!inputText.value) {
        ElMessage.warning(`请输入文字...`)
        return;
      }
      if (!textContainer.value) return;
      const scaleNum = isNaN(Number(imgScale.value)) ? 1 : Number(imgScale.value)
      const canvas = await html2canvas(textContainer.value, { 
        backgroundColor: isCustomBgColor.value ? customBgColor.value : null, // 设置背景色为 null 以生成透明背景
        scale: scaleNum
      });
      canvas.toBlob(async (blob) => {
        if (!blob) return;
        const file = new File([blob], 'text-image.png', { type: 'image/png' });
        try {
          const response = await toUpload(file);

          if (response.status === 200) {
            imageUrl.value = response?.data?.data?.link;
          } else {
            throw new Error('Upload failed');
          }
        } catch (error) {
          console.error('Error uploading file:', error);
        }
      }, 'image/png');
    };
    const toCopy = <T extends Row>(row: T) => {
      if(!imageUrl.value) {
        ElMessage.warning(`请先前往生成图片`)
        return
      }
      copy(imageUrl.value, '图片链接复制成功！')
    }
    const isCustomBgColorChange = <T extends Row>(sel: T) => {
      if(!sel) {
        customBgColor.value = '#ffffff'
      }
    }
    const customCss = () => {
      isCustomJson.value = true
    }
    const customDialogSave = () => {
      customJson.value = formData.json
      isCustomJson.value = false
    }
    const customDialogCancel = () => {
      formData.json = defalutJson
      customJson.value = ''
      isCustomJson.value = false
    }
    const clearCustomCss = () => {
      customJson.value = ''
    }
    return {
      customDialogSave,
      customDialogCancel,
      customJson,
      formData,
      isCustomJson,
      customCss,
      clearCustomCss,
      customBgColor,
      isCustomBgColor,
      textContainerStyle,
      isCustomBgColorChange,
      imgScale,
      fontSize,
      fontWeight,
      fontColor,
      fontFamily,
      inputText,
      textContainer,
      imageUrl,
      generateAndUploadImage, toCopy}
  }
}
</script>

<style lang="scss">
.text2img {
    font-size: 12px;
  &-edit {
    display: flex;
    justify-content: center;
    align-items: center;
    &__icon {
      margin: 0 10px 0 0;
    }
  }
  .text2img-config {
    margin:0 0 10px;
    padding-left: 25px;
    display: flex;
    justify-content: flex-start;
    flex-flow: wrap;
    .config-item {
      width: 49%;
      margin-top: 10px;
      text-align: left;
      display: flex;
      justify-content: center;
      align-items: center;
      &:nth-child(2n) {
        margin-left: 2%;
      }
      .el-input-group__prepend {
      padding: 0 0 0 4px;
      }
      .el-input-group__append {
      padding: 0 4px 0 0;
      }
      pre {
        max-height: 130px;
        overflow: auto;
        padding: 10px;
        border-radius: 4px;
        background-color: #29292a;
        color: #e3af57;
        font-size: inherit;
        font-family: inherit;
        white-space: pre-wrap;
        white-space: -moz-pre-wrap;
        white-space: -pre-wrap;
        white-space: -o-pre-wrap;
        word-wrap: break-word;
      }
    }
  }
  .transform-btn {
    margin: 10px auto;
  }
  .text-container {
    position: absolute;
    top: -1000px;
    padding: 5px 10px;
    display: flex;
    justify-content: center;
    align-items: center;
    background-color: transparent;
  }
  .text2img-show {
    padding: 20px;
    border: 1px dashed #ddd;
    background: #f5f7fa;
    &__title {
      font-size: 12px;
    }
    .transform-img {
      display: flex;
      justify-content: center;
      align-items: center;
      .imgs {
        margin-top: 10px;
      }
    }
  }
  .text2img-dialog {
    max-width: 360px;
    .el-dialog__body {
      padding: 10px 20px;
      .tips {
        margin-top: 10px;
        font-size: 12px;
        line-height: 14px;
        text-align: left;
        color: #f76e6f;
      }
      .el-textarea__inner {
      background-color: #29292a;
      color: #e3af57;
      }
    }
  }
}
</style>
